package copy.application;

import copy.code.GenerateClassCodeStrategy;
import copy.express.ParseNodeStackStrategy;
import copy.meta.impl.ParseEasycopyMetaDataStrategyHandler;
import copy.scan.ScanStrategy;

import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import java.util.HashMap;
import java.util.Map;

/**
 * 核心流程: 入口 -> EasyCopyAnnotationProcessor.process()
 *         1. anno.process包: EasyCopyAnnotationProcessor
 *              a. laodTypeTransform()寻找类型转换器. 数据去向: EasyCopyAnnotationProcessor 中 transformMap
 *              b. doSolveEasyCopy()寻找EasyCopy修饰的接口. 数据去向: Application 中 classNameList
 *              c. runProcess()加载创建容器的各个功能组件,并启动组件
 *
 *         2. meta包: AbsParseMetaData: 解析元数据组件
 *              数据来源: Application 中 classNameList
 *              数据去向: Application 中 interfaceMetaDataMap
 *              a. solveMethodDefinition() 解析方法的元数据信息
 *              b. solvePropertyMappingDefinition() 解析属性的映射关系元数据信息
 *         3. express包: AbsParseNodeStackStrategy: 表达式Stack栈形式存储,并将中缀表达式变后缀表达式
 *              数据来源: Property 中 resourcePropertyName
 *              数据去向: Property 中 nodeStack
 *              a. toNodeStack() 生成栈节点.
 *              数据来源: Property 中 nodeStack
 *              数据取向: Property 中 nodeStack
 *              b. toSuffixStack() 将栈节点,由中缀表达 转 后缀表达
 *
 *         注意: 4步操作的StackNode一定要深拷贝一份.因为StackNode是元数据.运行时,字段Node节点解析出的值,一定是不同的.
 *
 *         4. code包: :生成字节码
 *
 */
public class Application {


    //这是各个部分的组件
    private Map<Class,Process> processSingleFactory = new HashMap<>();

    //单例
    private static Application application = null;

    //必须属性: 处理组件间的耦合关系
    private static ProcessingEnvironment processingEnv;
    private static RoundEnvironment roundEnvironment;
    private Application(ProcessingEnvironment p, RoundEnvironment r){
        this.processingEnv = p;
        roundEnvironment = r;
    }
    public static void initSingleBean(ProcessingEnvironment p,RoundEnvironment r){
        processingEnv  = p;
        roundEnvironment = r;
    }
    //创建对象
    public static Application getScanSingleBean() {
        if (application == null){
            application = new Application(processingEnv,roundEnvironment);
        }
        return application;
    }

    public void prepare(){
        //创建Scan扫描器
        ScanStrategy.initSingleBean(roundEnvironment);
        processSingleFactory.putIfAbsent(  ScanStrategy.class , ScanStrategy.getScanSingleBean() );
        //创建元数据解析器
        processSingleFactory.putIfAbsent( ParseEasycopyMetaDataStrategyHandler.class , ParseEasycopyMetaDataStrategyHandler.getScanSingleBean() );
        //NodeStack表达式.中缀表达式转后缀表达式
        processSingleFactory.putIfAbsent( ParseNodeStackStrategy.class, ParseNodeStackStrategy.getSingleBean() );
        //字节码生成器
        GenerateClassCodeStrategy.init(processingEnv);
        processSingleFactory.putIfAbsent( GenerateClassCodeStrategy.class,GenerateClassCodeStrategy.getSingleBean() );
    }

    public Process getStrategy(Class cls){
        return processSingleFactory.get(cls);
    }


}
